/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.flexengine.component;

import com.flexengine.engine.Priority;
import com.flexengine.utils.FontManager;
import com.flexengine.view.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.text.DecimalFormat;

/**
 * @author Luann R. Athayde
 * @version 1.0
 * @since 1.0
 */
public class ProgressBar extends GameComponent {

    public static final int LOAD_BAR_NONE         = 0;
    public static final int LOAD_BAR_PERCENT_INFO = 1;
    public static final int LOAD_BAR_NUMERIC_INFO = 2;
    
    private double progress;
    private double maxProgress;
    private int    infoType;
    
    private Color  backgroundColor;
    private Color  progressColor;
    private Color  borderColor;
    private double roundRectWidth;
    private double roundRectHeight;
    
    private Color  infoColor;
    
    private DecimalFormat df;
    private String        infoPattern;
    
    private boolean indeterminate;
    
    private int inderminateX, moveX;
    private int inderminatePercentSize;
    
    public ProgressBar(double progress, double maxProgress) {
        super("", Priority.NORMAL_PRIORITY, 0, 0, new Dimension());
        this.progress = progress;
        this.maxProgress = maxProgress;
        this.infoType = LOAD_BAR_PERCENT_INFO;
        this.backgroundColor = new Color(111, 111, 111);
        this.progressColor = new Color(180,200,255);
        this.borderColor = Color.WHITE;
        this.roundRectWidth = this.roundRectHeight = 0;
        this.infoColor = Color.BLACK;
        this.infoPattern = "0";
        this.df = new DecimalFormat(infoPattern);
        this.indeterminate = false;
        this.inderminateX = (int)getX();
        this.moveX = 3;
        this.inderminatePercentSize = 20;
    }
    public ProgressBar() {
        this(0,100);
    }

    @Override
    public void update(Long time, Long totalTime) {
        inderminateX += moveX;
        int width = (size.width*inderminatePercentSize)/100;
        if( inderminateX > getX()+size.width-width ) {
            moveX = -moveX;
            inderminateX = (int)getX()+size.width-width;
        }
        if( inderminateX <= getX() ) {
            moveX = -moveX;
            inderminateX = (int)getX();
        }
    }

    @Override
    public void render(Graphics g) {
        // -- progress...
        if( backgroundColor!=null ) {
            g.setColor(backgroundColor);
        } else {
            g.setColor(Color.BLACK);
        }
        g.fillRoundRect((int)x, (int)y, size.width, size.height, (int)roundRectWidth, (int)roundRectHeight);
        // -- progress...
        if( indeterminate ) {
            renderIndeterminate(g);
        } else {
            renderProgress(g);
        }
        // -- border...
        if( borderColor!=null ) {
            g.setColor(borderColor);
        } else {
            g.setColor(Color.WHITE);
        }
        g.drawRoundRect((int)x, (int)y, size.width, size.height, (int)roundRectWidth, (int)roundRectHeight);
        // -- info...
        if( infoColor!=null ) {
            g.setColor(infoColor);
        } else {
            g.setColor(Color.RED);
        }
        //----------------------------------------------------------------------
        String info = getInfo();
        //----------------------------------------------------------------------
        Font font = FontManager.getFont(FontManager.defaultFont,1,size.height/2);
        Rectangle2D rect = font.getStringBounds(info, new FontRenderContext(null, true, true));
        g.setFont(font);
        g.drawString(info, (int)(x+size.width/2-rect.getWidth()/2), (int)(y+size.height/2+size.height/4));
    }
    
    private void renderProgress(Graphics g) {
        int width = (int)((progress*size.width)/maxProgress);
        if( progressColor!=null ) {
            g.setColor(progressColor);
        } else {
            g.setColor(Color.LIGHT_GRAY);
        }
        g.fillRoundRect((int)x, (int)y, width, size.height, (int)roundRectWidth, (int)roundRectHeight);
    }
    
    private void renderIndeterminate(Graphics g) {
        int width = (size.width*inderminatePercentSize)/100;
        if( progressColor!=null ) {
            g.setColor(progressColor);
        } else {
            g.setColor(Color.LIGHT_GRAY);
        }
        g.fillRoundRect(inderminateX, (int)y, width, size.height, (int)roundRectWidth, (int)roundRectHeight);
    }

    private String getInfo() {
        String info = "";
        if( infoType==LOAD_BAR_NUMERIC_INFO ) {
            info = df.format(progress)+"/"+df.format(maxProgress);
        } else if( infoType==LOAD_BAR_PERCENT_INFO ) {
            info = df.format((progress*100d)/maxProgress)+"%";
        }
        return info;
    }
    
    public synchronized void setInfoPattern(String infoPattern) {
        this.infoPattern = infoPattern;
        this.df = new DecimalFormat(infoPattern);
    }

    public String getInfoPattern() {
        return infoPattern;
    }
    
    public void incrementProgress() {
        progress++;
        if( progress>maxProgress ) {
            progress = maxProgress;
        }
    }
    
    public double getProgress() {
        return progress;
    }

    public void setProgress(double progress) {
        if( progress>=0 ) {
            this.progress = progress;
            if( this.progress>maxProgress ) {
                this.progress = maxProgress;
            }
        }
    }

    public double getMaxProgress() {
        return maxProgress;
    }

    public void setMaxProgress(double maxProgress) {
        if( maxProgress>0 ) {
            this.maxProgress = maxProgress;
        }
    }

    public int getInfoType() {
        return infoType;
    }

    public void setInfoType(int infoType) {
        this.infoType = infoType;
    }

    public Color getBackgroundColor() {
        return backgroundColor;
    }

    public void setBackgroundColor(Color backgroundColor) {
        this.backgroundColor = backgroundColor;
    }

    public Color getBorderColor() {
        return borderColor;
    }

    public void setBorderColor(Color borderColor) {
        this.borderColor = borderColor;
    }

    public double getRoundRectWidth() {
        return roundRectWidth;
    }

    public void setRoundRectWidth(double roundRectWidth) {
        this.roundRectWidth = roundRectWidth;
    }

    public double getRoundRectHeight() {
        return roundRectHeight;
    }

    public void setRoundRectHeight(double roundRectHeight) {
        this.roundRectHeight = roundRectHeight;
    }

    public void setProgressColor(Color progressColor) {
        this.progressColor = progressColor;
    }

    public Color getProgressColor() {
        return progressColor;
    }

    public void setInfoColor(Color infoColor) {
        this.infoColor = infoColor;
    }

    public Color getInfoColor() {
        return infoColor;
    }

    public void setIndeterminate(boolean indeterminate) {
        this.indeterminate = indeterminate;
    }

    public boolean isIndeterminate() {
        return indeterminate;
    }
    
    public void setRoundRect(double roundRectWidth, double roundRectHeight) {
        setRoundRectWidth(roundRectWidth);
        setRoundRectHeight(roundRectHeight);
    }
    
}